package GameState;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;


import GameState.Projectiles.CannonBall;
import GameState.Ships.PirateShip;
import Server.Player;
import Server.Request;
import Server.Requests.MovementRequest;
import Server.Requests.ShootingRequest;
import Server.Requests.TurningRequest;

public class GameState implements Iterable<GamePiece>{

	private static final int CANNON_DAMGE = 1;
	private static final int UPPER_BOUND = +1000;
	private static final int LOWER_BOUND = -1000;


	private List<CannonBall> mBalls;
	private Map<Player, PirateShip> mPlayerToShips;
	//private List<Request> mPlayerRequests;


	private class GameStateIterator implements Iterator<GamePiece>{


		private Iterator<PirateShip> mShipIterator;
		private Iterator<CannonBall> mCannonBallIterator;

		public GameStateIterator(){

			mShipIterator = mPlayerToShips.values().iterator();
			mCannonBallIterator = mBalls.iterator();


		}

		@Override
		public boolean hasNext() {



			return mShipIterator.hasNext() || mCannonBallIterator.hasNext();
		}

		@Override
		public GamePiece next() {

			if(mShipIterator.hasNext()){

				return mShipIterator.next();

			} else if ( mCannonBallIterator.hasNext()) {

				return mCannonBallIterator.next();

			}

			return null;
		}

		@Override
		public void remove() {
			// TODO Auto-generated method stub

		}


	}


	public GameState()
	{
		mPlayerToShips = new HashMap<Player, PirateShip>();
		mBalls = new LinkedList<CannonBall>();
	}


	protected void removeBall(CannonBall c){


		mBalls.remove(c);

	}

	protected void addBall(CannonBall c){

		mBalls.add(c);

	}

	/*public void update(){

		//Updates the wind movement
		//Wind theWind = myWind.get(0);
		//theWind.windUpdate();
		updateBalls();
		updateShips();




	}

//	private void updateShips(){
//
//		//TODO Finnish putting in all the ship stuff.
//		//Move all the request stuff into the requst and player classes
//		for(Request r : mPlayerRequests){
//
//			PirateShip tempship  = mPlayerToShips.get(r.getPlayer());
//
//
//			switch (r.getMovementRequest())
//			{
//
//			case SPEED_UP:
//					
//				break;
//
//			case LAY_ANCHOR:
//				break;
//
//			}
//
//			switch (r.getShootingRequest())
//			{
//
//			case SHOOT_LEFT:
//				break;
//
//			case SHOOT_RIGHT:
//				break;
//
//			}
//
//			switch (r.getTurningRequest())
//			{
//
//			case TURN_LEFT:
//				break;
//
//			case TURN_RIGHT:
//				break;
//
//			}
//
//		}


		//upates all the ships movements
		for(Entry<Player, PirateShip> entry : mPlayerToShips.entrySet()){



			System.out.println(count);

			if (mShips.get(count).getRequests() == null){

				continue lookThroughShips;
			}

			RequestsTypes [] requests = mShips.get(count).getRequests();

			if(requests[0] != null){
				mShips.get(count).moveForward();
			}
			if(requests[1] == RequestsTypes.TURN_RIGHT){
				mShips.get(count).turnRight();
			}else if(requests[1] == RequestsTypes.TURN_LEFT){

				mShips.get(count).turnLeft();
			}

			if(requests[2] != null){

				mShips.get(count).slowDown();
			}


			if(requests[3] != null){

				mBalls.addAll(mShips.get(count).shootLeft());

			}

			if(requests[4] != null){

				mBalls.addAll(mShips.get(count).shootRight());

			}

			if( requests[5] != null){

				mShips.get(count).layAnchor();

			}

			mShips.get(count).moveShip();
			mShips.get(count).updateAmmo();


			if(mShips.get(count).getHealth() <= 0){


				mShips.get(count).destroy();

			}

			mShips.get(count).worldWrap(UPPER_BOUND, LOWER_BOUND);
			mShips.get(count).slowDown();



		}

	}

	private  void updateBalls(){



		List<CannonBall> removeList = new LinkedList<CannonBall>();


		//goes though all the cannonballs in the list
		for (CannonBall currentBall : mBalls){


			//looks to see if if I should delete it
			if( currentBall.shouldDelete()){

				removeList.add(currentBall);

			} else{

				currentBall.move();

				//looks to see if that ball collides with any other ball
				for(Entry<Player, PirateShip> collideEntry : mPlayerToShips.entrySet()){


					
					 * Checks to see if the cannon ball can collide with the cannon ball 
					 
					if(collideEntry.getValue().collide(currentBall)){

						collideEntry.getValue().hit(CANNON_DAMGE);
						mBalls.remove(currentBall);

					}


				}
			}


			for(CannonBall removeBall : removeList){

				mBalls.remove(removeBall);
			}



		}

	}
*/


	@Override
	public Iterator<GamePiece> iterator() {
		return new GameStateIterator();
	}


	public void addPlayer(Player p) {
		// TODO Auto-generated method stub
		
	}


	public void removePlayer(Player p) {
		
		
	}

	public PirateShip getShip(Player currentPlayer){
		
		return mPlayerToShips.get(currentPlayer);
		
	}

}
